import React, { memo, useMemo, useEffect, useState } from 'react';
import BaseNode from './BaseNode';
import { usePreviousNodes } from '@/hooks/usePreviousNodes';

/**
 * SQL读入
 * @param {*} props 
 * @returns 
 */
export const SqlNode = memo((props) => {
  const { data, type } = props ?? {}
  const { label, tableName, columns } = data ?? {}
  const errMessage = useMemo(() => {
    if (!tableName) return '配置有误/不完整，请修改';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [tableName, columns]);
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

/**
 * 预处理
 * @param {*} props 
 * @returns 
 */
export const PreprocessNode = memo((props) => {
  const { id, data, type } = props
  const { label, columns } = data
  const preNodes = usePreviousNodes(id)
  const errMessage = useMemo(() => {
    if (!preNodes?.length) return '缺少输入，请拖拽连线';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns])
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => {
  return pre.data === next.data
})
/**
 * 转置
 * @param {*} props 
 * @returns 
 */
export const TransposeNode = memo((props) => {
  const { id, data, type } = props
  const { label, columns } = data
  const preNodes = usePreviousNodes(id)
  const errMessage = useMemo(() => {
    if (!preNodes?.length) return '缺少输入，请拖拽连线';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns])
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

/**
 * 合并
 * @param {*} props 
 * @returns 
 */
export const UnionNode = memo((props) => {
  const { id, data, type } = props
  const { label, columns } = data
  const preNodes = usePreviousNodes(id)
  const errMessage = useMemo(() => {
    if (!preNodes?.length) return '缺少输入，请拖拽连线';
    if (preNodes?.length < 2 ) return '缺少输入，请至少连接两个上游节点';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns])
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

/**
 * 聚合
 * @param {*} props 
 * @returns 
 */
export const AggregateNode = memo((props) => {
  const { id, data, type } = props
  const { label, columns } = data
  const preNodes = usePreviousNodes(id)
  const errMessage = useMemo(() => {
    if (!preNodes?.length) return '缺少输入，请拖拽连线';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns])
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

/**
 * 关联
 * @param {*} props 
 * @returns 
 */
export const JoinNode = memo((props) => {
  const { id, data, type } = props ?? {}
  const { label, columns } = data ?? {}
  const preNodes = usePreviousNodes(id)

  const errMessage = useMemo(() => {
    if (!(preNodes?.length === 2)) return '缺少输入，请连接两个上游节点';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns]);
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

/**
 * 写出
 * @param {*} props 
 * @returns 
 */
export const SinkNode = memo((props) => {
  const { id, data, type } = props
  const { label, columns } = data
  const preNodes = usePreviousNodes(id)
  const errMessage = useMemo(() => {
    if (!preNodes?.length) return '缺少输入，请拖拽连线';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns])
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

/**
 * 落盘
 * @param {*} props 
 * @returns 
 */
export const PersistNode = memo((props) => {
  const { id, data, type } = props
  const { label, columns } = data
  const preNodes = usePreviousNodes(id)
  const errMessage = useMemo(() => {
    if (!preNodes?.length) return '缺少输入，请拖拽连线';
    if (!columns?.length) return '无有效输出';
    return null;
  }, [preNodes, columns])
  return <BaseNode label={label} type={type} errMessage={errMessage} />
}, (pre, next) => pre.data === next.data)

SqlNode.displayName = 'SqlNode'
PreprocessNode.displayName = 'PreprocessNode'
AggregateNode.displayName = 'AggregateNode'
UnionNode.displayName = 'UnionNode'
JoinNode.displayName = 'JoinNode'
SinkNode.displayName = 'SinkNode'
PersistNode.displayName = 'PersistNode'
TransposeNode.displayName = 'TransposeNode'

export const NodeTypes = Object.freeze({
  SqlNode,
  TransposeNode,
  UnionNode,
  AggregateNode,
  JoinNode,
  SinkNode,
  PersistNode,
  PreprocessNode
})